#include "networkmanager.h"
#include "qtconcurrentrun.h"
#include "source/errordialogmanager.h"
#include "source/logger.h"
#include <QTimeZone>
#include "source/tools.h"

NetworkManager* NetworkManager::m_instance = nullptr;
QMutex NetworkManager::m_mutex;

NetworkManager* NetworkManager::instance()
{
    if (!m_instance) {
        QMutexLocker locker(&m_mutex);
        if (!m_instance) {
            m_instance = new NetworkManager();
        }
    }
    return m_instance;
}

void NetworkManager::queryMacAddress12Chars()
{
    m_uniqueSequence = getObfuscatedSerial();
    LogDebug << "m_uniqueSequence:" << m_uniqueSequence;
    emit deviceInfoChanged();
}
QByteArray NetworkManager::encryptSequence(const QString &sequence)
{
    // Simple hash-based encryption using SHA-256
    QByteArray combined = sequence.toUtf8() + m_secretKey.toUtf8();
    QByteArray hash = QCryptographicHash::hash(combined, QCryptographicHash::Sha256);
    return hash.toHex();
}

NetworkManager::NetworkManager(QObject *parent)
    : QObject(parent), m_networkManager(new QNetworkAccessManager(this)), m_secretKey("mysecretkey")
{

    m_worker = new NetworkWorker();
    m_worker->setencryptSequence(encryptSequence(m_uniqueSequence));
    QThread *workerThread = new QThread(this);
    m_worker->moveToThread(workerThread);
    workerThread->start();

    connect(m_worker, &NetworkWorker::serverConnectedChanged, this, &NetworkManager::serverConnectedChanged);
    connect(m_worker, &NetworkWorker::currentVersionChanged, this, &NetworkManager::currentVersionChanged);
    connect(m_worker, &NetworkWorker::latestVersionChanged, this, &NetworkManager::latestVersionChanged);
    connect(m_worker, &NetworkWorker::updateContentChanged, this, &NetworkManager::updateContentChanged);
    connect(m_worker, &NetworkWorker::updateTimeChanged, this, &NetworkManager::updateTimeChanged);
    connect(m_worker, &NetworkWorker::deviceInfoChanged, this, &NetworkManager::deviceInfoChanged);
    connect(m_worker, &NetworkWorker::logMessage, this, &NetworkManager::logMessage);
    connect(m_worker, &NetworkWorker::logMessage, this, &NetworkManager::logMessage);

    queryMacAddress12Chars();
}

QString NetworkManager::deviceName() const
{
    return m_worker->m_deviceName;
}


QDateTime NetworkManager::registrationDate() const
{
    return m_worker->m_registrationDate;
}

QString NetworkManager::stregistrationDate() const
{
    return m_worker->m_stregistrationDate;
}


QString NetworkManager::owner() const
{
    return m_worker->m_owner;
}

QDateTime NetworkManager::expiryDate() const
{
    return m_worker->m_expiryDate;
}

QString NetworkManager::stexpiryDate() const
{
    return m_worker->m_stexpiryDate;
}

QString NetworkManager::endUser() const
{
    return m_worker->m_endUser;
}

QString NetworkManager::releasedBy() const
{
    return  m_worker->m_releasedBy;
}

QString NetworkManager::serialnumber() const
{
    return m_uniqueSequence;
}

bool NetworkManager::serverConnected() const
{
    return m_worker->m_serverConnected;
}

QString NetworkManager::currentVersion() const
{
    return m_worker->m_currentVersion;
}

QString NetworkManager::latestVersion() const
{
    return m_worker->m_latestVersion;
}

QString NetworkManager::updateContent() const
{
    return m_worker->m_updateContent;
}

QDateTime NetworkManager::updateTime() const
{
    return m_worker->m_updateTime;
}

void NetworkManager::sendRunningStatus()
{
    QMetaObject::invokeMethod(m_worker, "sendRunningStatus", Qt::QueuedConnection);
}

void NetworkManager::sendCompressedImage(const QString &imagePath)
{
    QMetaObject::invokeMethod(m_worker, "sendCompressedImage", Qt::QueuedConnection, Q_ARG(QString, imagePath));
}

void NetworkManager::getDeviceInfo()
{
    QMetaObject::invokeMethod(m_worker, "getDeviceInfo", Qt::QueuedConnection);
}

void NetworkManager::downloadUpdate()
{
    QMetaObject::invokeMethod(m_worker, "downloadUpdate", Qt::QueuedConnection);

}

void NetworkManager::connectToServer()
{
    //LogDebug << "Attempting to connectToServer" ;
    bool success = QMetaObject::invokeMethod(m_worker, "connectToServer", Qt::QueuedConnection);
    if (!success) {
        LogDebug << "Failed to invoke method connectToServer";
    }
}

void NetworkManager::checkForUpdates()
{
    QMetaObject::invokeMethod(m_worker, "checkForUpdates", Qt::QueuedConnection);
}


